home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / tagsgen.exe / ARGLIST.C < prev    next >
C/C++ Source or Header  |  1991-09-25  |  10KB  |  344 lines

  1. /*
  2.  EPSHeader
  3.  
  4.    File: arglist.c
  5.    Author: J. Kercheval
  6.    Created: Thu, 09/05/1991  20:01:35
  7. */
  8. /*
  9.  EPSRevision History
  10.  
  11.    J. Kercheval  Thu, 09/05/1991  20:09:36  creation
  12.    J. Kercheval  Thu, 09/05/1991  21:51:00  add DestroyArgList()
  13.    J. Kercheval  Tue, 09/10/1991  23:51:03  add calls to external_cleanup() before exit(1)
  14.    J. Kercheval  Wed, 09/11/1991  00:23:32  add ArgCopy()
  15.    J. Kercheval  Wed, 09/18/1991  21:14:24  fix realloc bug in ArgRegisterArg
  16.    J. Kercheval  Wed, 09/25/1991  14:05:13  add support for sorted argument lists
  17.    J. Kercheval  Wed, 09/25/1991  16:47:35  fix bug in ArgList memory reallocation
  18. */
  19.  
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #include "arglist.h"
  25. #include "log.h"
  26.  
  27.  
  28. #define FILE_LIST_BLOCK_SIZE 2048       /* allocation block size */
  29.  
  30. /* the cleanup routine for problem exiting */
  31. extern void external_cleanup(void);
  32.  
  33. /*----------------------------------------------------------------------------
  34.  *
  35.  * CreateArgList() will allocate the memory needed for the use of an ArgList
  36.  * variable and will set the initial values of the list.  If sorted_list is
  37.  * TRUE then the list is maintained in sorted order when additions are made
  38.  * through the register arg routines.
  39.  *
  40.  ---------------------------------------------------------------------------*/
  41.  
  42. ArgList CreateArgList(BOOLEAN sorted_list)
  43. {
  44.     ArgList arg;
  45.  
  46.     if ((arg = (ArgList) malloc(sizeof(struct ArgListStruct)))
  47.         == NULL) {
  48.         log_message("# CreateArgList() -- out of memory");
  49.         log_close();
  50.         external_cleanup();
  51.         exit(1);
  52.     }
  53.  
  54.     /* initialize and allocate the arglist */
  55.     arg->size = FILE_LIST_BLOCK_SIZE;
  56.     arg->num_files = 0;
  57.     arg->num_args = 0;
  58.     arg->sorted = sorted_list;
  59.  
  60.     /* allocate the argv list */
  61.     if ((arg->argv =
  62.          (char **) malloc(arg->size * sizeof(char *))) == NULL) {
  63.         log_message("# CreateArgList() -- out of memory");
  64.         log_close();
  65.         external_cleanup();
  66.         exit(1);
  67.     }
  68.  
  69.     /* return the pointer */
  70.     return arg;
  71. }
  72.  
  73.  
  74. /*----------------------------------------------------------------------------
  75.  *
  76.  * DestroyArgList() will deallocate the memory used by the ArgList variable.
  77.  *
  78.  ---------------------------------------------------------------------------*/
  79.  
  80. void DestroyArgList(ArgList arglist)
  81. {
  82.     /* remove the elements */
  83.     while (arglist->num_args) {
  84.         arglist->num_args--;
  85.         free(arglist->argv[arglist->num_args]);
  86.     }
  87.  
  88.     /* remove the argv element */
  89.     free(arglist->argv);
  90.  
  91.     /* remove the arglist itself */
  92.     free(arglist);
  93. }
  94.  
  95.  
  96. /*----------------------------------------------------------------------------
  97.  *
  98.  * ArgToOutputStream() will output all files in argv to stdout
  99.  *
  100.  ---------------------------------------------------------------------------*/
  101.  
  102. void ArgToOutputStream(FILE * output_file, ArgList arglist)
  103. {
  104.     FILE *input_file;           /* file ptr */
  105.  
  106.     char **argv;                /* the actual argument list */
  107.     int argc;                   /* the number of elements in arglist */
  108.  
  109.     int c;                      /* temporary character */
  110.  
  111.     argc = arglist->num_args;
  112.     argv = arglist->argv;
  113.  
  114.     while (argc) {
  115.         if ((input_file = fopen(*argv, "r")) == (FILE *) NULL) {
  116.             log_message("# ArgToOutputStream() -- file open error");
  117.         }
  118.         else {
  119.             c = fgetc(input_file);
  120.             while (!feof(input_file)) {
  121.                 fputc(c, output_file);
  122.                 c = fgetc(input_file);
  123.             }
  124.             fclose(input_file);
  125.         }
  126.         argc--;
  127.         argv++;
  128.     }
  129. }
  130.  
  131.  
  132. /*----------------------------------------------------------------------------
  133.  *
  134.  * ArgIsMember() returns true if s is a member of the string array arg
  135.  *
  136.  ---------------------------------------------------------------------------*/
  137.  
  138. BOOLEAN ArgIsMember(ArgList argf, char *arg)
  139. {
  140.     int i;
  141.     int start, end;
  142.     int compare;
  143.  
  144.     if (argf->sorted) {
  145.  
  146.         /* do a binary search */
  147.         start = 0;
  148.         end = argf->num_args - 1;
  149.  
  150.         while (start <= end) {
  151.  
  152.             /* compute new index and compare to argument */
  153.             i = (start + end) / 2;
  154.             compare = stricmp(arg, argf->argv[i]);
  155.  
  156.             /* if the element is found return true */
  157.             if (!compare)
  158.                 return TRUE;
  159.  
  160.             /* narrow the search or stop the search if needed */
  161.             if (compare < 0) {
  162.  
  163.                 /* if the index is already equal to end then the element is
  164.                  * not present and start is equal to end, move start beyond
  165.                  * end */
  166.                 if (end == i)
  167.                     start++;
  168.                 end = i;
  169.             }
  170.             else {
  171.  
  172.                 /* if start and end are the same then the element is not
  173.                  * present */
  174.                 if (start == i)
  175.                     i++;
  176.                 start = i;
  177.             }
  178.         }
  179.     }
  180.     else {
  181.  
  182.         /* Do a linear search, loop through until we determine if the arg is
  183.          * currently an element of argf */
  184.         for (i = 0; (unsigned int) i < argf->num_args; i++) {
  185.             if (!stricmp(argf->argv[i], arg)) {
  186.                 return TRUE;
  187.             }
  188.         }
  189.     }
  190.  
  191.     /* if we reach here, it is not in the arglist */
  192.     return FALSE;
  193. }
  194.  
  195.  
  196. /*----------------------------------------------------------------------------
  197.  *
  198.  * ArgCopy() copies all the elements of argfrom to argto while adding
  199.  * internal bookkeeping variables
  200.  *
  201.  ---------------------------------------------------------------------------*/
  202.  
  203. void ArgCopy(ArgList argto, ArgList argfrom)
  204. {
  205.     unsigned int i;
  206.  
  207.     /* loop through until we have copied them all */
  208.     for (i = 0; i < argfrom->num_args; i++) {
  209.         ArgRegisterArg(argto, argfrom->argv[i]);
  210.     }
  211.  
  212.     /* add the number of file arguments to the destination */
  213.     argfrom->num_files += argto->num_files;
  214. }
  215.  
  216.  
  217. /*----------------------------------------------------------------------------
  218.  *
  219.  * ArgRegisterArg() places an argument in the ArgList array and increments
  220.  * arglist->num_args
  221.  *
  222.  ---------------------------------------------------------------------------*/
  223.  
  224. void ArgRegisterArg(ArgList argf, char *arg)
  225. {
  226.     char *arg_string;
  227.  
  228.     int i;
  229.     int start, end;
  230.     int compare;
  231.     int insertion_index;
  232.  
  233.     /* allocate the file name array and copy */
  234.     if ((arg_string = malloc(sizeof(char) * (strlen(arg) + 1))) ==
  235.         (char *) NULL) {
  236.         log_message("# RegisterArg() -- out of memory");
  237.         log_close();
  238.         external_cleanup();
  239.         exit(1);
  240.     }
  241.     strcpy(arg_string, arg);
  242.  
  243.     /* reallocate the file list array if needed */
  244.     if (argf->num_args >= argf->size) {
  245.  
  246.         /* update the arglist size */
  247.         argf->size += FILE_LIST_BLOCK_SIZE;
  248.  
  249.         /* reallocate the block */
  250.         if ((argf->argv = realloc(argf->argv, argf->size * sizeof(char *))) ==
  251.             NULL) {
  252.             log_message("# RegisterArg() -- out of memory");
  253.             log_close();
  254.             external_cleanup();
  255.             exit(1);
  256.         }
  257.     }
  258.  
  259.     if (argf->sorted) {
  260.  
  261.         /* do a binary insertion sort, by first doing the binary search and
  262.          * then an insertion */
  263.         start = 0;
  264.         end = argf->num_args - 1;
  265.         i = 0;
  266.         compare = -1;
  267.  
  268.         while (start <= end) {
  269.  
  270.             /* compute new index and compare to argument */
  271.             i = (start + end) / 2;
  272.             compare = stricmp(arg, argf->argv[i]);
  273.  
  274.             /* if the element is already in the list then return */
  275.             if (!compare)
  276.                 return;
  277.  
  278.             /* narrow the search or stop the search if needed */
  279.             if (compare < 0) {
  280.  
  281.                 /* if the index is already equal to end then the element is
  282.                  * not present and start is equal to end, move start beyond
  283.                  * e